package controller.data.base;

import base.R;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import lombok.SneakyThrows;
import utils.ExceptionUtil;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public abstract class BaseController extends HttpServlet {

    protected Map<String, Method> methodMap;

    @SneakyThrows
    public BaseController() {
        methodMap = new HashMap<>();
        String[] urls = {"page", "save", "update", "remove"};
        for (String url : urls) {
            Method method = getClass().getMethod(genDefaultMethodName(url), HttpServletRequest.class, HttpServletResponse.class);
            methodMap.put(url, method);
        }
    }

    protected void addDefaultMethodInfo(Class<?> clazz) {
        Method[] methods = clazz.getDeclaredMethods();
        List<String> methodNameList = Arrays.stream(methods).map(Method::getName).collect(Collectors.toList());
        List<String> existMethodNameList = methodMap.values().stream().map(Method::getName).collect(Collectors.toList());
        CollUtil.filter(methodNameList, i -> !existMethodNameList.contains(i));
        Method[] declaredMethods = clazz.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            if (methodNameList.contains(declaredMethod.getName())) {
                addMethod(declaredMethod.getName(), declaredMethod);
            }
        }
    }


    @SneakyThrows
    private String genDefaultMethodName(String url) {
        return "handle" + StrUtil.upperFirst(url);
    }

    protected void addMethod(String url, Method method) {
        if (url.contains("addDefaultMethodInfo")) {
            return;
        }
        methodMap.put(url, method);
    }

    @Override
    protected synchronized void service(HttpServletRequest request, HttpServletResponse response) {
        try {
            Method method = methodMap.get(extractAction(request.getRequestURI()));
            if (method == null) {
                R.error().setData("找不到servlet处理方法").push(response);
                return;
            }
            method.invoke(this, request, response);
        } catch (Exception e) {
            e.printStackTrace();
            R.error().setMsg("请求时出现异常: " + ExceptionUtil.getExceptionMessage(e)).push(response);
        }
    }

    private String extractAction(String uri) {
        String[] parts = uri.split("/");
        return parts[parts.length - 1];  // 获取最后一部分作为动作
    }


    protected abstract void handlePage(HttpServletRequest request, HttpServletResponse response);

    protected abstract void handleSave(HttpServletRequest request, HttpServletResponse response);

    protected abstract void handleUpdate(HttpServletRequest request, HttpServletResponse response);

    protected abstract void handleRemove(HttpServletRequest request, HttpServletResponse response);
}
